/*!
 * 树节点对象.
 * ecp.qzz.treenode.js
 * 创建：QZZ
 * 日期：2014-03-01
 */
define(["qzz.base"], function() {
	
	var qzz = window.qzz;
	
	qzz.treenode = qzz.Class({
		/**
		 * 初始化函数.
		 */
		init:function() {
		    this.className = "TreeNode";
		    //this.logInfo("TreeNode.create");
		    //所有节点的序号
		    this.recNo = qzz.treenode.recNo ++;
		    if(qzz.treenode.recNo > 1000000000) {
		    	qzz.treenode.recNo = 1;
		    }
		    //父节点
		    this.pNode = null;
		    //子节点数组
		    this.cNode = [];
		    //排序节点、状态、序号的json
		    this.sortNode = {};
		    this.sortState = {};
		    this.sortIndex = {};
		    this.sortChanged = {};
		    //排序字段
		    this.sortKey = "default";
		    //展开状态
		    this.expanded = true;
		    //所有子节点及自己的总数
		    this.allCount = 1;
		    //当前可见的数量（收缩的时候就只有自己一个）
		    this.visibleCount = 1;
		    //子节点数量
		    this.count = 0;
		    //子节点序号
		    this.index = 0;
		    //在树中的总序号
		    this.scrIndex = 0;
		    //层次号
		    this.level = 0;
		    //扩展对象
		    this.data = null;
		    //扩展的属性对象
		    this.option = null;
		    //总编码
		    this.fullcode = "";
		    //当前层次的编码
		    this.code = "";
		    //显示的text
		    this.text = "";
		    //id值
		    this.id = "";
		    //选择状态
			//this.selectState = false;
		    this.checkState = false;
			//
			this.enable = true;
			//下级选择数量
			//this.childSelectCount = 0;
			this.childCheckCount = 0;
			//过滤状态的节点
			this.nodeState = null;
			this.filterState = false;
	    },
	    /**
	     * 保存当前状态.
	     */
	    saveState:function() {
	    	 if(!this.filterState) {
		    	 var cNode = [];
		    	 for(var i = 0; i < this.count; i++) {
		    		 cNode[i] = this.cNode[i];
		    	 }
		    	 //保存各种需要的状态.
		    	 this.nodeState = {"cNode":cNode,
		    	              "allCount":this.allCount,
		    	              "visibleCount":this.visibleCount,
		    	              "count":this.count,
		    	              "index":this.index,
		    	              "scrIndex":this.scrIndex,
		    	              "expanded":this.expanded
		    	 };
		    	 this.filterState = true;
	    	 }
	    },
	    /**
	     * 加载状态.
	     */
	    loadState:function() {
	    	if(this.nodeState != null && this.filterState) {
	    		var cNode = this.nodeState.cNode;
	    		this.cNode = [];
	    		for(var i = 0, len = cNode.length; i < len; i++) {
	    			this.cNode[i] = cNode[i];
	    		}
	    		this.allCount = this.nodeState.allCount;
	    		this.visibleCount = this.nodeState.visibleCount;
	    		this.count = this.nodeState.count;
	    		this.index = this.nodeState.index;
	    		this.scrIndex = this.nodeState.scrIndex;
	    		this.expanded = this.nodeState.expanded;
	    		this.sortNode = {};
	    		this.sortState = {};
	    		this.sortIndex = {};
	    		this.filterState = false;
	    		this.nodeState = null;
	    	}
	    },
	    /**
	     * 是否叶子节点.
	     */
	    isLeaf:function() {
	    	return this.count === 0;
	    },
	    /**
	     * 子节点数量.
	     */
	    getCount:function() {
	    	return this.count;
	    },
	    /**
	     * 运算各个节点的所有子节点.
	     * @param addCount 增加的数量
	     */
	    cacAllCount:function(addCount, cacFilter) {
	    	this.allCount += addCount;
	    	var pNode = this.pNode;
	    	while(pNode != null) {
	    		pNode.allCount += addCount;
	    		pNode = pNode.pNode;
	    	}
	    	//如果过滤的情况下，增加节点，也需要把缓存的状态一并计算
	    	if(cacFilter && this.filterState) {
	    		this.nodeState.allCount += addCount;
		    	var pNode = this.pNode;
		    	while(pNode != null) {
		    		pNode.nodeState.allCount += addCount;
		    		pNode = pNode.pNode;
		    	}
	    	}
	    	pNode = null;
	    },
	    /**
	     * 计算可见节点的数量.
	     * @param addVCount 增量显示的数量
	     * 
	     */
	    cacVisibleCount:function(addVCount, cacFilter) {
	    	var pNode = this.pNode;
	    	while(pNode != null && pNode.expanded) {
	    		pNode.visibleCount += addVCount;
	    		pNode = pNode.pNode;
	    	}
	    	if(pNode != null) {
    			pNode.visibleCount += addVCount;
    		}
	    	//如果过滤的情况下，增加节点，也需要把缓存的状态一并计算
	    	if(cacFilter && this.filterState) {
	    		pNode = this.pNode;
	    		while(pNode != null && pNode.nodeState.expanded) {
	    			pNode.nodeState.visibleCount += addVCount;
		    		pNode = pNode.pNode;
	    		}
	    		if(pNode != null) {
	    			pNode.nodeState.visibleCount += addVCount;
	    		}
	    	}
	    	pNode = null;
	    },
	    /**
	     * 节点展开.
	     */
	    expand:function() {
	    	if(!this.expanded) {
	    		this.expanded = true;
	    		var addVCount = this.visibleCount - 1;
	    		this.cacVisibleCount(addVCount, false);
	    		addCount = null;
	    	}
	    },
	    /**
	     * 节点收缩.
	     */
	    collapse:function() {
	    	if(this.expanded) {
	    		this.expanded = false;
	    		var addVCount = (this.visibleCount - 1) * (-1);
	    		this.cacVisibleCount(addVCount, false);
	    		addCount = null;
	    	}
	    },	  
	    /**
	     * 节点增加.
	     * @param node 节点对象
	     */
	    addNode:function(node) {
	    	if(node instanceof qzz.treenode) {
		    	this.cNode.push(node);
		    	node.pNode = this;
		    	node.index = this.count;
		    	node.level = this.level + 1;
		    	node.scrIndex = this.scrIndex + this.count + 1;
		    	this.count ++;		   
		    	if(this.filterState) {
		    		this.nodeState.cNode.push(node);
		    		node.saveState();
		    		node.nodeState.index = this.nodeState.count;
		    		this.nodeState.count++;
		    	}
		    	
	    		var sindex = this.count - 1;
	    		var index = sindex;
	    		//处理排序的状态下，要在排序的列表中添加，并标识变化标志
		    	for(var key in this.sortState) {
			    	this._insertSort(key, sindex, index, this);
		    	}
		    	//do all count;
		    	var addCount = node.allCount;
		    	this.cacAllCount(addCount, true);
		    	allCount = null;
		    	//do all v count
		    	var addVCount = node.visibleCount;
		    	if(!node.expanded) {
		    		addVCount = 1;
		    	}
		    	this.visibleCount += addVCount;
		    	if(this.expanded === true) {
		    	    this.cacVisibleCount(addVCount, true);
		    	}
                if(this.filterState) {
		    		this.nodeState.visibleCount += addVCount;
		    	}
		    	addVCount = null;
		    	return true;
	    	}
	    	return false;
	    },
	      /**
	       * 处理排序时插入的序号问题.
	       * @param sindex 真实序号
	       * @param pNode 父节点
	       */
	      _insertSort:function(fieldName, sindex, index, pNode) {
				var si = pNode.sortIndex[fieldName];
				var sn = pNode.sortNode[fieldName];
				if(sn == null && si == null) return;
				//重置序号对齐
				for(var i = sn.length; i > sindex; i--) {
					//序号重新排序
					si[i] = si[i - 1];
					if(si[i] >= index) {
						si[i]++;
					}
				}
				si[i] = index;
				i--;
				for(; i >= 0; i--) {
					if(si[i] >= index) {
						si[i]++;
					}
				}
				
				//重置序号对齐
				for(var i = sn.length; i > index; i--) {
					
					//节点重新排序序号
					sn[i] = sn[i - 1];
					if(sn[i].nodeIndex >= sindex) {
						sn[i].nodeIndex++;
					}
				}
				sn[i] = {nodeIndex:sindex,cnode:[]};
				i--;
				for(; i >= 0; i--) {
					if(sn[i].nodeIndex >= sindex) {
						sn[i].nodeIndex++;
					}
				}
	      },
	    /**
	     * 插入节点对象.
	     * @param index 序号
	     * @param node 节点对象
	     */
	    insertNode:function(index, node) {
	    	if(node instanceof qzz.treenode) {
		    	if(index >= 0 && index <= this.count) {
		    		for(var i = this.count; i > index; i--){
		    			this.cNode[i] = this.cNode[i-1];
		    			this.cNode[i].index = i;
		    		}
		    		//定义recNo变量.
		    		var scrIndex, recNo = null;
		    		if(index < this.count) {
		    		    scrIndex = this.cNode[index].scrIndex;
		    		}
		    		if(index > 0) {
		    			//如果是过滤的话，真实的插入位置以前一条明细所在的位置的后面.
		    		    recNo = this.cNode[index - 1].recNo;
		    		}
		    		node.pNode = this;
		    		node.index = index;
		    		node.scrIndex = scrIndex;
                    node.level = this.level + 1;
                    this.cNode[index] = node; 
		    		this.count ++;
		    		
		    		//过滤状态下需要处理缓存内的状态.
		    	    if(this.filterState) {
		    	    	var cIndex = index;
		    		    for(var i = this.nodeState.count; i > index; i--) {
		    		    	if(recNo != null && this.nodeState.cNode[i - 1].recNo === recNo) {
		    		    		cIndex = i;
		    		    		break;
		    		    	}
		    		    	this.nodeState.cNode[i] = this.nodeState.cNode[i - 1];
			    			this.nodeState.cNode[i].nodeState.index = i;
		    		    }
		    		    this.nodeState.cNode[cIndex] = node;
		    		    node.saveState();
		    		    node.nodeState.index = cIndex;
		    		    this.nodeState.count++;
		    	    }		    	    
		    	    //处理排序的状态下，要在排序的列表中添加，并标识变化标志
			    	for(var key in this.sortState) {
				    	this._insertSort(key, index, index, this);
			    	}
		    		//do all count
		    		//this.allCount += node.allCount;	
		    		var addCount = node.allCount;
		    		this.cacAllCount(addCount, true);
			    	//do all v count
			    	var addVCount = node.visibleCount;
			    	if(!node.expanded) {
			    		addVCount = 1;
			    	}
			    	this.visibleCount += addVCount;
			    	if(this.expanded === true) {
			    	    this.cacVisibleCount(addVCount, true);
			    	}
	                if(this.filterState) {
			    		this.nodeState.visibleCount += addVCount;
			    	}
			    	addVCount = null;
			    	return true;
		    	}
	    	}
	    	return false;
	    },
	      /**
	       * 处理排序时插入的序号问题.
	       * @param sindex 真实序号
	       * @param pNode 父节点
	       */
	      _delSort:function(fieldName, index, pNode) {
				var si = pNode.sortIndex[fieldName];
				var sn = pNode.sortNode[fieldName];
				if(sn == null && si == null) return;
				var sindex = sn[index].nodeIndex;
				var i = 0;
				//重置序号对齐
				for(var ilen = sn.length; i < ilen - 1; i++) {
					//序号重新排序
					if(i >= sindex) {
						si[i] = si[i + 1];						
					}
					if(si[i] >= index) {
						si[i]--;
					}
					//节点重新排序序号
					//序号重新排序
					if(i >= index) {
						sn[i] = sn[i + 1];						
					}
					if(sn[i].nodeIndex >= sindex) {
						sn[i].nodeIndex--;
					}
				}
				//删除节点
				delete si[i];
				sn.splice(i, 1);
	      },
	    /**
	     * 删除节点.
	     * @param index 节点序号
	     */
	    delNode:function(index, free) {
		    if(index >= 0 && index < this.count) {
		    	var free = (free != false);
		    	// && this.cNode[index].isLeaf()) {
		    	var dNode = this.cNode[index];	
		    	for(var i = index; i < this.count - 1; i++) {
		    		this.cNode[i] = this.cNode[i + 1];
		    		this.cNode[i].index = i;
		    	}
		    	this.cNode[this.count - 1] = undefined;
		    	this.cNode.splice(this.count - 1, 1);
		    	this.count --;
		    	//过滤状态下需要处理缓存内的状态.
		    	if(this.filterState && free) {
		    		for(var i = dNode.nodeState.index; i < this.nodeState.count - 1; i++) {
		    			this.nodeState.cNode[i] = this.nodeState.cNode[i + 1];
		    			this.nodeState.cNode[i].nodeState.index = i;
		    		}
		    		this.nodeState.cNode[this.nodeState.count - 1] = undefined;
		    		this.nodeState.cNode.splice(this.nodeState.count - 1, 1);
			    	this.nodeState.count --;
		    	}
		    	//处理排序的状态下，要在排序的列表中添加，并标识变化标志
		    	for(var key in this.sortState) {
			    	this._delSort(key, index, this);
		    	}
		    	//do all count
                var addCount = dNode.allCount * (-1);
		    	this.cacAllCount(addCount, true && free);
		    	//do all v count
		    	var addVCount = dNode.visibleCount * (-1);
		    	if(!dNode.expanded) {
		    		addVCount = -1;
		    	}	    
		    	this.visibleCount += addVCount;
		    	if(this.expanded === true) {
		    	   this.cacVisibleCount(addVCount, true && free);
		    	}
		    	if(free) {
	                if(this.filterState) {
			    		this.nodeState.visibleCount += addVCount;
			    	}
		    		dNode.pNode = null;
		    		dNode.cNode = [];
		    		dNode.sortNode = {};
			    	dNode.destroy();
			    	dNode = null;
		    	}
		    	return true;
		    }
		    return false;
	    },

	    /**
	     * 获取节点.
	     * @param index 获取节点序号
	     */
	    getNode:function(index) {
	    	if(index >= 0 && index < this.count) {
	    		return this.cNode[index];
	    	}
	    	return null;
	    },
	    /**
	     * 获取全局序号.
	     */
	    getIndex:function() {
	    	return this.scrIndex;
	    },
	    /**
	     * 克隆.
	     */
	    clone:function() {
	    	var nNode = new qzz.treenode();
	    	nNode.recNo = this.recNo;
//	    	nNode.pNode = this.pNode;
//	    	nNode.cNode = [];
	    	nNode.expand = this.expand;
	    	nNode.allCount = this.allCount;
	    	nNode.index = this.index;
	    	nNode.data = this.data;
	    	nNode.text = this.text;
	    	nNode.id = this.id;
	    	nNode.count = this.count;
	    	return nNode;
	    },
	    /**
	     * 复制.
	     * @param node 节点对象
	     */
	    copy:function(node) {
	    	if(node instanceof qzz.treenode) {
	    		this.recNo = node.recNo;
//	    		this.pNode = node.pNode;
//		    	this.cNode = [];
                this.expand = node.expand;
                this.allCount = node.allCount;
                this.index = node.index;
                this.data = node.data;
                this.text = node.text;
                this.id = node.id;
                this.count = node.count;
	    	}
	    },
	    /**
	     * 注析掉当前类.
	     * @ignore
	     */
	    destroy:function() {
			// 复制静态方法
	    	var that = this;
	    	that.pNode = null;
	    	that.level = null;
	    	that.sortNode = {};
	    	that._hasDestroy = true;
	    	setTimeout(function(){
	    		if(that != null) {
	    			for(var name in that) {
	    				if(name === "baseprototype") {
	    					that[name] = null;
	    				} else {
		    				if(that[name] != null && typeof that[name] === "object" && typeof that[name].destroy === "function") {
		    					try {
		    					    that[name].destroy();
		    		    		} catch(e) {
		    		    			console.info(name + "[Destroy]Error:" + e.message);
		    		    		}
		    				}
		    				delete that[name];	
	    				}
	    			}
	    			that._hasDestroy = true;
	    		}
	    	}, 5000);
	    }
	});
	/**
	 * 节点序号初始化.
	 */
	qzz.treenode.recNo = 1;
	return qzz.treenode;
});
	